package com.chap6;

import java.util.concurrent.locks.ReentrantLock;

/**
 * <p>
 * <code>ReentrantLockDemo</code>
 * </p>
 *
 * @author junbao3
 * TODO
 * @date 2023-03-16 14:38
 * Copyright (C) 2021 IFlyTek. All rights reserved.
 */
public class ReentrantLockDemo1 {
    private final ReentrantLock lock = new ReentrantLock();
    private static int tickets = 8;

    public void buyTicket(){
        if (tickets>0){//读操作
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"购买了第"+tickets-- +"张票");//写操作
        }else {
            System.out.println("票已经卖完了，"+Thread.currentThread().getName()+"抢票失败");
        }

    }

    public static void main(String[] args) {
        ReentrantLockDemo1 ticketSystem = new ReentrantLockDemo1();
        for (int i = 1; i <=10 ; i++) {//10个人抢8张票
            Thread thread = new Thread(()->{
                ticketSystem.buyTicket();
            },"线程"+i);
            thread.start();
        }
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("剩余票数：" + tickets);

    }
}

/*
并发场景下，多线程有读有写，如果没有做额外的处理，就会出现线程安全问题
10个人买8张票  剩余票数-2 或者有两个线程买到同一张票 超卖问题

单机场景下，加锁解决
synchronized或者lock
二者性能差不多，synchronized后期做了很多优化


某些情况下，synchronized比cas性能更高
synchronized底层用的就是cas，不存synchronized比cas性能更高的时候
cas是有竞争的场景，偏向锁是单个线程，有另外一个线程来，偏向锁会撤销，偏向锁撤销比轻量级锁会更费性能。先撤销，再到轻量级锁
撤销的过程中，再加上cas，反而不如cas

重量级锁，竞争比较激烈，建议使用ReentrantLock，ReentrantLock比synchronized性能提高10%
不是很激烈的场景，比如框架（中间件）初始化的时候，有些数据的加载，只会涉及线程之间的交替执行，用synchronized就可以
dubbo很多地方用到synchronized

*/
